package com.neusoft.elmboot.filter;


import com.neusoft.elmboot.common.AutheAuthoResp;
import com.neusoft.elmboot.common.constant.IgnoreConstant;
import com.neusoft.elmboot.common.properties.JwtProperties;
import com.neusoft.elmboot.common.utils.JwtUtil;
import com.neusoft.elmboot.po.UserEntity;
import com.neusoft.elmboot.service.UserService;
import com.neusoft.elmboot.service.impl.UserServiceImpl;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

@Slf4j
public class JwtFilter extends OncePerRequestFilter {

    private static final String adminSecretKey = "elm";
    private long adminTtl = 7200000;
    private String adminTokenName = "elm-token";



    private UserService userService = new UserServiceImpl() ;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String requestUrl = httpServletRequest.getRequestURI();
        log.info("-------1.JwtFilter.doFilter() -> requestUrl : "+requestUrl+" , referer : "+httpServletRequest.getHeader("Referer"));
        if(IgnoreConstant.IGNORE_AUTHORIZE_URLS.length > 0) {
            for (String ignoreAuthorizeUrl : IgnoreConstant.IGNORE_AUTHORIZE_URLS) {
                if (requestUrl.indexOf(ignoreAuthorizeUrl)>-1) {
                    filterChain.doFilter(httpServletRequest, httpServletResponse);
                    System.out.println(requestUrl+ "-----ignore authorize url!");
                    return;
                }
            }
        }
        //获取token
        String token = httpServletRequest.getHeader(adminTokenName);
        //校验token
        log.info("-----------开始校验jwt---------");
        Claims claims = JwtUtil.parseJWT(adminSecretKey, token);
        if (claims==null){
            return;
        }
        Integer userId = (Integer) claims.get("userId");
        System.out.println("---------------------------------------------------------");
//        String username = JwtUtil.getUsernameFromToken(token);

        Object obj = claims.get("authorities");
        List<LinkedHashMap> getAuthorities = null;
        if (obj instanceof List){
            getAuthorities = (List<LinkedHashMap>) obj;
        }
        StringBuffer sb = new StringBuffer();

        /*for (GrantedAuthority getAuthority : getAuthorities) {
            sb.append(getAuthority.getAuthority()).append(",");
            System.out.println(getAuthority.toString());

        }*/
        for (LinkedHashMap linkedHashMap : getAuthorities) {

            String authority = (String) linkedHashMap.get("authority");
            System.out.println(authority);
            sb.append(authority).append(",");
        }
        String authStr = "";
        if (sb.length()>0) {
            authStr = sb.substring(0,sb.length()-1);
        }
        String username = "张三丰";
        String userName = (String) claims.get("userName");

        List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(authStr);
        UsernamePasswordAuthenticationToken upaToken = new UsernamePasswordAuthenticationToken(userName, null, authorities);
        SecurityContextHolder.getContext().setAuthentication(upaToken);
        boolean hasPermission = checkPermission(authorities, requestUrl);
        log.info("-------------hasPermission"+hasPermission);
        if (hasPermission) {
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        } else {
            // 如果用户没有权限访问该URL，则返回无权限提示

            log.info("------当前用户无权访问！");
//               response.sendError(HttpServletResponse.SC_FORBIDDEN);
            AutheAuthoResp.accessDeniedResponse(httpServletRequest,httpServletResponse);
        }



    }

    private boolean checkPermission(List<GrantedAuthority> authorities, String requestUrl) {
        if (authorities != null) {
            // 根据用户的权限信息，判断是否有权限访问该URL
            for (GrantedAuthority permission : authorities) {
                if (permissionMatchesUrl(permission.getAuthority(), requestUrl)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     *
     * @param permission - 数据库中的权限URL  ： GET /food/list
     * @param requestUrl - 当前浏览器请求的URL : /elm/food/list
     * @return
     */
    private boolean permissionMatchesUrl(String permission, String requestUrl) {
        log.info("-------------------db authorityUrl=["+permission+"] requestUrl="+requestUrl);
        if (permission == null) {
            return false;
        }
        if ("*".equals(permission)){
            return true;
        }
//        String s = permission.split(" ")[1];
        String[] perArray = permission.split(" ");
        if (null !=  perArray && perArray.length > 1) {
            return requestUrl.indexOf(perArray[1]) > -1 ;
        }
        return false ;
    }



}
